﻿namespace HuwmanCode

open System
open System.Runtime.CompilerServices

[<AutoOpen>]
[<Extension>]
[<RequireQualifiedAccess>]
module Func =
    /// <summary>
    /// Invokes a function and invokes a compensation action should an exception occur.
    /// </summary>
    /// <param name="compensate">The action to invoke should an exception occur.</param>
    /// <param name="func">The function to invoke.</param>
    /// <return>An option value. None if an exception is caught, otherwise Some('T).</return>
    [<Extension>]
    let Try (compensate:exn Action) (func:Func<_>) = 
        try
            Some(func.Invoke())
        with e ->
            if compensate <> null then compensate.Invoke e
            None

    /// <summary>
    /// Invokes a function and invokes a compensation action and reraises the exception should an exception occur.
    /// </summary>
    /// <param name="compensate">The action to invoke should an exception occur.</param>
    /// <param name="func">The function to invoke.</param>
    /// <return>The result of calling func ().</return>
    [<Extension>]
    let TryWithRethrow (compensate:exn Action) (func:Func<_>) =
        try
            func.Invoke()
        with e -> 
            if compensate <> null then compensate.Invoke e
            reraise()